package io.renren.common.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.renren.common.constant.Constant;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Map参数转wapper工具类
 * */
public class ParamUtil {
    //查询关系
    static  final String[] logicArray = {"eq","ne","lt","le","gt","ge","in","notin","like","nlike"};
    static final List<String> logic = Arrays.asList(logicArray);
    //数据类型
    static  final String[] dateType = {"int","long","date","time","double"};
    /**
     * 带权限的拼接参数
     * */
    public static QueryWrapper toWapperR(Map<String, Object> params,String tableAlias){
        QueryWrapper q= toWapper(params,tableAlias);

        return q;
    }
    /**
     * map转成wapper
     * key: 关系_字段_数据类型 例如 ，like_name  eq_age_int
     * 字段必须驼峰格式，不能有下划线
     * 数据类型默认可以省略，可以不写
     * */
    public static QueryWrapper toWapper(Map<String, Object> params,String tableAlias){
        QueryWrapper qw = new QueryWrapper();
        String tAlias =null;
        boolean haveAlias = false;

        String finalTableAlias = tableAlias;
        if(StringUtils.isNotBlank(tableAlias)){
            tAlias = tableAlias+".";
            haveAlias=true;
        }


        /**
         * 拼接权限
         * */
        if(params.get(Constant.SQL_FILTER)!=null){
            qw.apply((String)params.get(Constant.SQL_FILTER));
        }
        for(String key : params.keySet()){
           String[] paramInfo =  key.split("_");
           if(paramInfo.length<2 || !logic.contains(paramInfo[0]) ){
               continue;
           }


           Object value =params.get(key);
            if(value==null|| (value instanceof String && StringUtils.isBlank((String) value))){
                continue;
            }
            if(value instanceof String){
                value=((String)value).trim();
            }
           //长度为3说明不是默认String类型
           if(paramInfo.length==3){
               value = transType(value,paramInfo[2]);
           }


            String field =toUnderlineCase(paramInfo[1]);
            String itemField =field ;
            if(haveAlias){
                itemField =tAlias+field;
            }

           //qw.a
            switch (paramInfo[0]){
                case "eq":qw.eq(itemField,value);break;
                case "ne":qw.ne(itemField,value);break;
                case "lt":qw.lt(itemField,value);break;
                case "le":qw.le(itemField,value);break;
                case "gt":qw.gt(itemField,value);break;
                case "ge":qw.ge(itemField,value);break;
                case "in":qw.in(itemField,value);break;
                case "like":qw.like(itemField,value);break;
                case "nlike":final Object pv = value;qw.and(wy->{
                    QueryWrapper likeqw =(QueryWrapper) wy;
                    String temfield =field;
                    if(field.contains("$$")){
                        temfield= temfield.replace("$$","@");
                    }
                    String[] cfield = temfield.split("\\$");
                    for(int i =0 ;i<cfield.length;i++){
                    if(i!=0){
                        likeqw.or();
                    }
                    String itemAlia = finalTableAlias;
                    if(cfield[i].contains("@")){
                       String[] alisAndName = cfield[i].split("@");
                       itemAlia=alisAndName[0];
                        cfield[i]=alisAndName[1];
                    }
                    if(itemAlia!=null){
                        likeqw.like( itemAlia+"."+cfield[i],pv);
                    }else{
                        likeqw.like(cfield[i],pv);
                    }

                };//return likeqw;
                });
                break;
                case "notin":qw.notIn(field,value);break;
            }
        }
        if(params.get("orderBy")!=null){
            String cols = (String) params.get("orderBy");
            for(String col :cols.split(",")){
                if(col.contains(" desc")){
                    qw.orderByDesc(col);
                }else{
                    qw.orderByAsc(col);
                }
            }

        }
        return  qw;
    }

    /**
     * 转换数据类型
     * */
    public static Object transType(Object value ,String dateType ){
        if(value == null){
            return value;
        }
        String strValue = (String) value;
        switch (dateType){
            case "int" :return Integer.valueOf(strValue);
            case "long" :return Long.valueOf(strValue);
            case "double" :return Double.valueOf(strValue);
            case "date" :return DateUtils.stringToDate(strValue,DateUtils.DATE_PATTERN);
            case "time" :return DateUtils.stringToDate(strValue,DateUtils.DATE_TIME_PATTERN);
        }
        return value;
    }
    /**
     * 驼峰转 下划线
     * userName  ---->  user_name
     * user_name  ---->  user_name
     *
     * @param camelCaseStr 驼峰字符串
     * @return 带下滑线的String
     */
    public static String toUnderlineCase(String camelCaseStr) {
        if (camelCaseStr == null) {
            return null;
        }
        // 将驼峰字符串转换成数组
        char[] charArray = camelCaseStr.toCharArray();
        StringBuffer buffer = new StringBuffer();
        //处理字符串
        for (int i = 0, l = charArray.length; i < l; i++) {
            if (charArray[i] >= 65 && charArray[i] <= 90) {
                buffer.append("_").append(charArray[i] += 32);
                //只有数字，字母和$可以拼接，其他参数不允许，防止sql注入
            } else if(charArray[i]==36 || (charArray[i] >= 65 && charArray[i] <= 90) || (charArray[i] >= 48 && charArray[i] <= 57) || (charArray[i] >= 97 && charArray[i] <= 122) ){
                buffer.append(charArray[i]);
            }
        }
        return buffer.toString();
    }
}
